﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Web;
using wnet.admin;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;

namespace wnet.admin.Comm
{

    /// <summary>
    /// 传感器数据
    /// </summary>
    public class SensorAlarmBusiness : CatchingAlarmProcessor
    {
        /// <summary>
        /// 探测器字典
        /// </summary>
        Dictionary<int, int> SensorTypes = new Dictionary<int, int>() { };

        private int PackageLength = 83;
        /// <summary>
        /// 跳过记录显示点
        /// </summary>
        private int mSkipNum = 0;

        public ObservableCollection<ObservableCollection<Point>> localData = new ObservableCollection<ObservableCollection<Point>>();

        /// <summary>
        /// 数据坐标点 第一组数据和第二组数据的同步 数据源为第一组数据
        /// </summary>
        private Queue<int> mYPoint = new Queue<int>();

        private int position = 0;

        private Project Project = new Project();

        //private FileRecord filerecord = new FileRecord();
        private string ViewalarmContent = string.Empty;
        private string circleContent = string.Empty;
        private Dictionary<double, string> circleTypeDic = new Dictionary<double, string>() { { 1, "内层" }, { 2, "中间层" }, { 3, "外层" } };
        internal static event EventHandler AlarmChangeEvent = null;
        /// <summary>
        /// 按照累计点显示小波
        /// </summary>
        private int xTotalPointValue = 0;
        /// <summary>
        /// 给矩阵数组赋值的锁
        /// </summary>
        private static readonly object flawDetectionIndexLock = new object();


        /// <summary>
        /// 根据算法组装数据 n路传感器数据+ 位置
        /// </summary>
        private double[] dbValue;


        ///// <summary>
        ///// 本地测试软件平台数据
        ///// </summary>
        //private ObservableCollection<AlarmInfoModel> localData = new ObservableCollection<AlarmInfoModel>();

        private void Abstract_AlarmEvent(string flag, object sender)
        {

        }

        #region Construct
        public SensorAlarmBusiness(string procesorName, int mThreadCount) : base(procesorName, mThreadCount)
        {
            //this.localData = ConstDefine.AlarmInfos;
            //ConstDefine.InitFlawDdetectionData();
            dbValue = new double[ConstDefine.Project.TotalPointNum * ConstDefine.Project.SenSorNum * 2];

            _allDataList.Clear();
            SensorTypes.Clear();
        }

        public void Init()
        {
           
        }
        #endregion

        #region Private Method

        List<int> listEB900D0A = new List<int>();

        int mDetectorIndex = 0;

        public override void Process(object obj)
        {
            byte[] allByte = obj as byte[];
            try
            {
                int indexEB = 0;
                for (int bNum = 0; bNum < allByte.Length; bNum++)
                {
                    if (bNum + PackageLength <= allByte.Length)
                    {
                        if ((allByte[bNum] == 0xEB && allByte[bNum + 1] == 0x90) && (allByte[bNum + PackageLength - 2] == 0x0D && allByte[bNum + PackageLength - 1] == 0x0A))
                        {
                            if (SensorTypes.Count != 2 && !SensorTypes.ContainsKey(allByte[bNum + 3]))
                            {
                                SensorTypes.Add(allByte[bNum + 3], SensorTypes.Count);
                            }
                            SensorTypes.TryGetValue(allByte[bNum + 3], out mDetectorIndex);
                            if (mDetectorIndex == 0)
                            {
                                mDetectorIndex = 1;
                            }
                            else
                            {
                                mDetectorIndex = 0;
                            }
                            DealUnData_new(allByte.Skip(bNum).Take(PackageLength).ToArray(), mDetectorIndex);
                            bNum += PackageLength - 1;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

        private void DealUnData_new(byte[] allByte, int startSenSorIndex)
        {
            try
            {

                byte[] data = allByte;

                if (data.Length < PackageLength)
                {
                    return;
                }
                if (data[0] != 0xEB && data[1] != 0x90)
                {
                    return;
                }
                if (data[PackageLength - 2] != 0x0D && data[PackageLength - 1] != 0x0A)
                {
                    return;
                }

                byte[] positionByte = new byte[] { data[11], data[10], data[9], data[8] };
                int position = BitConverter.ToInt32(positionByte, 0);

                position = Math.Abs(position);
                dynamic value = 0;
                int index = 0;
                ConstDefine.Project.SenSorNum = 32;
                for (int j = 12; j <= 12 + (ConstDefine.Project.SenSorNum - 1) * 2; j += 2)
                {
                    value = BitConverter.ToUInt16(new byte[] { data[j + 1], data[j] }, 0);
                    Point point = new Point();
                    point.X = (int)(position);
                    point.Y = (int)(value);
                    int indexData = index + startSenSorIndex * ConstDefine.Project.SenSorNum;
                    int mPointNum = 500;
                    lock (ConstDefine.FlawDdetectionData[index + startSenSorIndex * ConstDefine.Project.SenSorNum])
                    {
                        ConstDefine.FlawDdetectionData[index + startSenSorIndex * ConstDefine.Project.SenSorNum].Add(point);
                    }
                    index++;
                }

                int flawDetectionIndex = 0;
                for (int i = 0; i < 1; i++)
                {
                    if (ConstDefine.FlawDdetectionData[0].Count >= ConstDefine.Project.TotalPointNum && ConstDefine.FlawDdetectionData[32].Count >= ConstDefine.Project.TotalPointNum)
                    {
                        //dbValue = new double[ConstDefine.Project.TotalPointNum * ConstDefine.Project.SenSorNum * 2];
                        flawDetectionIndex = 0;

                        int row = ConstDefine.Project.SenSorNum * 2;
                        int col = 250;
                        double[,] sensordata = new double[row, col];

                        for (int k = 0; k < ConstDefine.Project.SenSorNum * 2; k++)
                        {
                            for (int j = 0; j < ConstDefine.Project.TotalPointNum; j++)
                            {
                                //dbValue[flawDetectionIndex++] = ConstDefine.FlawDdetectionData[k][j].Y;
                                sensordata[k, j] = ConstDefine.FlawDdetectionData[k][j].Y;
                            }
                            //dbValue[flawDetectionIndex++] = ConstDefine.FlawDdetectionData[0][k].X;
                        }
                      
                        AlarmData.WireRrope_MagneticFluxLeakageCharacteristics(sensordata, row, col, position);

                        for (int k = 0; k < 64; k++)
                        {
                            ConstDefine.FlawDdetectionData[k].RemoveRange(0, ConstDefine.Project.TotalPointNum);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
                Console.WriteLine(ex.Message);
            }
        }
        List<byte> _allDataList = new List<byte>();
        // 83 1  * 64 = 一个完整数据包 点
        /// <summary>
        /// 数据的验证
        /// </summary>
        /// <param name="allByte"></param>
        /// <param name="startSenSorIndex"></param>
        private void DataCheck(List<byte> allByte, int startSenSorIndex, byte crc1, byte crc2)
        {
            try
            {
                int PackageLength = ConstDefine.Project.PackageLength;
                //byte[] data = allByte;
                List<byte> data = allByte;
                if (data.Count < PackageLength - 4)
                {
                    return;
                }
                if (data[0] != 0xEB && data[1] != 0x90)
                {
                    return;
                }

            }
            catch
            { }
        }


        string SnrContent = string.Empty;
        //private void DealWeite(int sensorIndex, double snr, double position1, int groupID, double position3, double[] y, double[] zzz)
        //{
        //    //flawDetectionAlarm = new FlawDetectionAlarm(Convert.ToInt32(position1), groupID, Convert.ToInt32(position3), y, zzz);
        //    //ViewalarmContent = $"{position1}";
        //    if (snr > 35)
        //    {
        //        SnrContent = "重度";
        //    }
        //    else if (snr < 20)
        //    {
        //        SnrContent = "轻度";
        //    }
        //    else
        //    {
        //        SnrContent = "中度";
        //    }
        //    AlarmInfoNew alarmInfo = new AlarmInfoNew();
        //    alarmInfo.Num = 0;
        //    alarmInfo.Position = position1.ToString();
        //    alarmInfo.PositionPulse = (int)position1;
        //    //alarmInfo.PositionMM = position1;
        //    alarmInfo.Info = position1.ToString();

        //    alarmInfo.SenSorNum360 = ConstDefine.Project.SenSorNum360;
        //    alarmInfo.SensorIndex = sensorIndex;
        //    if (ConstDefine.Project.IsSplitDisplay)
        //    {
        //        //int jiaodu = (360 / alarmInfo.SenSorNum360);
        //        //alarmInfo.SensorIndexContent = jiaodu + "°";
        //        int displayNum = 0;
        //        string strjiaodu = ConstDefine.Project.DisplayInfo1.GetJiaoduByDisplay(alarmInfo.SensorIndex);
        //        if (strjiaodu == "")
        //        {
        //            strjiaodu = ConstDefine.Project.DisplayInfo2.GetJiaoduByDisplay(alarmInfo.SensorIndex);
        //            if (strjiaodu != "")
        //            {
        //                displayNum = 2;
        //            }
        //        }
        //        else
        //        { displayNum = 1; }
        //        alarmInfo.SensorIndexContent2 = strjiaodu;
        //        alarmInfo.DisplayNum = displayNum;
        //    }
        //    else
        //    {
        //        int jiaodu = (360 / alarmInfo.SenSorNum360);
        //        alarmInfo.SensorIndexContent = jiaodu + "°";
        //        alarmInfo.SensorIndexContent2 = string.Format("{0}-{1}°", (sensorIndex - 1) * jiaodu, sensorIndex * jiaodu);
        //    }
        //    alarmInfo.SnrContent = SnrContent;
        //    alarmInfo.Snr = snr;
        //    Abstract_AlarmEvent("", alarmInfo);
        //    ConstDefine.AlarmInfoNewData.Add(alarmInfo);
        //    ConstDefine.AlarmCount++;
        //}

        //private void SaveY(string fileName, double[] y)
        //{
        //    string content = string.Empty;
        //    for (int i = 0; i < y.Length; i++)
        //    {
        //        content += y[i] + ",";
        //    }
        //    content = content.Remove(content.Length - 1, 1);
        //    filerecord.WriteFile(fileName, content);
        //}
        //private void SaveY(string fileName, double[] y)
        //{
        //    for (int i = 0; i < y.Length; i++)
        //    {
        //        filerecord.WriteFile(fileName, y[i].ToString());
        //    }

        //}
        int nameIndex = 1;
        private void SaveZZZ(double[] data)
        {
            int interval = 1001; // 间隔个数

            using (var writer = new StreamWriter($"./采集数据/{nameIndex++}output.csv"))
            {
                for (int i = 0; i < data.Length; i += interval)
                {
                    var chunk = data.Skip(i).Take(interval).ToArray();
                    string csvLine = string.Join(",", chunk);
                    writer.WriteLine(csvLine);
                }
            }
        }

        //private void SaveReport(AlarmInfoNew alarmInfoModel)
        //{
        //    string content = string.Empty;
        //    using (StreamWriter stream = new StreamWriter($"./报告.csv", true, Encoding.GetEncoding("GB2312")))
        //    {
        //        var chunk = alarmInfoModel.abnormalSensorList.ToArray();
        //        string csvLine = string.Join(" ", chunk);
        //        content = System.DateTime.Now.ToString("yyyy-M-dd hh:mm") + "," + alarmInfoModel.abnormalPos + "," + alarmInfoModel.abnormalSensorNum + "," + csvLine;
        //        stream.WriteLine(content);
        //    }
        //}

        //private void SaveZZZ(List<List<WinformWave.Model.PointXY>> data)
        //{
        //    using (var writer = new StreamWriter($"./采集数据/{nameIndex++}output.csv"))
        //    {
        //        for (int i = 0; i < 1000; i++)
        //        {
        //            string content = string.Empty;
        //            for (int j = 0; j < 64; j++)
        //            {
        //                content += data[j][i].Y + ",";
        //            }
        //            content = content.Remove(content.Length - 1, 1);
        //            writer.WriteLine(content);
        //        }
        //    }
        //}

        //private void SaveZZZ(string content)
        //{
        //    using (var writer = new StreamWriter($"./采集数据/{nameIndex++}output.csv"))
        //    {
        //        writer.Write(content);
        //    }
        //}

        //private double[] GetArray(List<List<WinformWave.Model.PointXY>> data, int length)
        //{
        //    double[] ret = new double[length];
        //    int index = 0;
        //    for (int i = 0; i < 1000; i++)
        //    {
        //        for (int j = 0; j < 64; j++)
        //        {
        //            ret[index++] = data[j][i].Y;
        //        }
        //    }

        //    return ret;
        //}


        #endregion
    }

    public class FlawDetection
    {
        [DllImport("DllTest.dll", EntryPoint = "wavetianjin", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)]
        internal static extern void wavetianjin(double[] y, double M, double N, ref double z, ref double position1, ref double position2, ref double position3, double[] zzz);

        [DllImport("Wave256dll.dll", EntryPoint = "wave256", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)]
        internal static extern void wave256(double[] y, double M, double N, ref double z, ref double position1, ref double position2, ref double position3, double[] zzz);


        //[DllImport("DllTest.dll", EntryPoint = "waveweite", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)]
        //internal static extern void waveweite(double[] y, double M, double N, double max1, ref double z, ref double position, double[] zzz);

        /// <summary>
        /// 
        /// </summary>
        /// <param name="y"></param>
        /// <param name="M">M是列数</param>
        /// <param name="N">N是行数</param>
        /// <param name="max1">max1是门限，默认为2e4，根据实际情况调整</param>
        /// <param name="z">有无缺陷，0表示无，1表示有</param>
        /// <param name="snr">信噪比</param>
        /// <param name="position">位置</param>
        /// <param name="position1">传感器编号</param>
        /// <param name="zzz">小波变换后的输出序列</param>
        [DllImport("weite_dll.dll", EntryPoint = "wave", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)]
        internal static extern void waveweite(double[] y, double M, double N, double max1, ref double z, ref double snr, ref double position, ref int position1, double[] zzz);


        /// <summary>
        /// 
        /// </summary>
        /// <param name="y"></param>
        /// <param name="M">M是列数</param>
        /// <param name="N">N是行数</param>
        /// <param name="max1">max1是门限，默认为2e4，根据实际情况调整</param>
        /// <param name="z">有无缺陷，0表示无，1表示有</param>
        /// <param name="snr">信噪比</param>
        /// <param name="position">位置</param>
        /// <param name="position1">传感器编号</param>
        /// <param name="zzz">小波变换后的输出序列</param>
        [DllImport("Dll3.dll", EntryPoint = "wave", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)]
        internal static extern void waveweiteDll3(double[] y, double M, double N, double max1, ref double z, ref double snr, ref double position, ref int position1, double[] zzz);


        [DllImport("DllTest.dll", EntryPoint = "wave722", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)]
        internal static extern double wave722(double[] y, double M, double N);


        [DllImport("ForeignObjectDetect.dll", EntryPoint = "FOD_judge", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)]
        internal static extern int FOD_judge(double[] y, int M, long N, ref byte jsonOut, int num);

        [DllImport("ForeignObjectDetect.dll", EntryPoint = "FOD_authenticateKey", CallingConvention = CallingConvention.Cdecl)]
        internal static extern int FOD_authenticateKey(string fileName);

        [DllImport("ForeignObjectDetect.dll", EntryPoint = "FOD_setParameter", CallingConvention = CallingConvention.Cdecl)]
        internal static extern int FOD_setParameter(string setParameter);

        [DllImport("ForeignObjectDetect.dll", EntryPoint = "FOD_setTraceFlag", CallingConvention = CallingConvention.Cdecl)]
        internal static extern void FOD_setTraceFlag(byte enable, string logFileName, int level, int maxSizeMB);
    }
}

